﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Windows.Media;
using System.Windows.Forms;
using Styx;
using Styx.Helpers;
using Styx.Common;
using Styx.CommonBot.POI;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System.Runtime.InteropServices;
using Styx.TreeSharp;
using Action = Styx.TreeSharp.Action;


namespace FeralKitty
{
    public partial class Classname : CombatRoutine
    {

        /*  http://elitistjerks.com/f73/t130906-feral_cat_mists_pandaria_5_0_4_a/
            1. Keep Faerie Fire up (if no other armor debuff).
            2. Keep Savage Roar up
            3. Use Tiger’s Fury/Nature's Vigil/Incarnation/Berserking/Force of Nature*
            4. Use Nature’s Swiftness/Healing touch to generate Wrath of Cenarius procs when GCD will not cause energy cap*
            5. Use Predatory Swiftness to generate Dream of Cenarius procs when GCD will not cause energy cap, preferably at 4CP.**
            6. Ferocious Bite if the boss has less than 25% hp remaining and Rip is near expiring.
            7. Ferocious Bite if you have 5 CP and at least 6 - 10 seconds on Savage Roar and Rip
            8. Keep 5 combo point Rip up.
            9. Keep Rake up
            10. Spend Omen of Clarity procs on Thrash if Thrash has less than 6 seconds remaining.
            11. Ravage to generate combo points if Ravage is available (Incarnation)
            12. Shred to generate combo points if Shred is available (Behind boss, berserk w/glyph, etc)
            13. Use Mangle to generate combo points.
            14. Maintain Thrash bleed if it will not interfere with Rake, Rip, or SR uptimes.
        */

        public string LastSpell = "";
        public string FaerieFire = "Faerie Fire";
        public string FaerieSwarm = "Faerie Swarm";
        public string SavageRoar = "Savage Roar";
        public string TigersFury = "Tiger's Fury";
        public string NaturesVigil = "Nature's Vigil";
        public string Incarnation = "Incarnation";
        public string Berserking = "Berserking";
        public string Berserk = "Berserk";
        public string ForceOfnature = "Force of Nature";
        public string NaturesSwiftness = "Nature's Swiftness";
        public string PredatorySwiftness = "Predatory Swiftness";
        public string FerociousBite = "Ferocious Bite";
        public string Rip = "Rip";
        public string Thrash = "Thrash";
        public string Ravage = "Ravage";
        public string Shred = "Shred";
        public string Mangle = "Mangle";
        public string Swipe = "Swipe";
        public string Rake = "Rake";
        public string Clearcasting = "Clearcasting";
        public string Lifeblood = "Lifeblood";
        public string HealingTouch = "Healing Touch";
        public string DreamOfCenarius = "DreamOfCenarius";
        public string CenarionWard = "Cenarion Ward";
        public string Rejuvenation = "Rejuvenation";
        public string MotW = "Mark of the Wild";
        public string Barkskin = "Barkskin";
        public string SurvivalInstincts = "Survival Instincts";
        public string FrenziedRegeneration = "Frenzied Regeneration";
        public string MightOfUrsoc = "Might of Ursoc";
        public string MightyBash = "Mighty Bash";
        public string SkullBash = "Skull Bash";
        public string Prowl = "Prowl";

        public static bool Paused = false;

        public string FF
        {
            get
            {
                if (SpellManager.HasSpell("Faerie Swarm"))
                {
                    return "Faerie Swarm";
                }
                return "Faerie Fire";
            }
        }

        #region GetAsyncKeyState

        [DllImport("user32.dll")]
        private static extern short GetAsyncKeyState(Keys vKey);

        #endregion

        #region castspell
        public void CastSpell(string spell, int kleur)
        {
            if (SpellManager.CanCast(spell))
            {
                SpellManager.Cast(spell);
                LastSpell = spell;
                LogMsg(spell, kleur);
            }
        }
        public void CastSpellID(int spell, int kleur)
        {
            if (SpellManager.CanCast(spell))
            {
                SpellManager.Cast(spell);
                //LastSpell = spell;
                //LogMsg(spell, kleur);
            }
        }
        #endregion castspell

        #region symbiosis
        public bool DeathCoil
        {
            get
            {
                if (IsBoss
                    && FeralKittySettings.AllPrefs.DeathCoil == 2)
                {
                    return true;
                }
                if (FeralKittySettings.AllPrefs.DeathCoil == 1)
                {
                    return true;
                }
                return false;
            }
        }
        public bool FeralSpirit
        {
            get
            {
                if (IsBoss
                    && FeralKittySettings.AllPrefs.FeralSpirit == 2)
                {
                    return true;
                }
                if (FeralKittySettings.AllPrefs.FeralSpirit == 1)
                {
                    return true;
                }
                return false;
            }
        }
        public bool ShatteringBlow
        {
            get
            {
                if (IsBoss
                    && FeralKittySettings.AllPrefs.ShatteringBlow == 2)
                {
                    return true;
                }
                if (FeralKittySettings.AllPrefs.ShatteringBlow == 1)
                {
                    return true;
                }
                return false;
            }
        }
        public bool SoulSwap
        {
            get
            {
                if (IsBoss
                    && FeralKittySettings.AllPrefs.SoulSwap == 2)
                {
                    return true;
                }
                if (FeralKittySettings.AllPrefs.SoulSwap == 1)
                {
                    return true;
                }
                return false;
            }
        }
        public bool DivineShield
        {
            get
            {
                if (IsBoss
                    && Me.HealthPercent <= FeralKittySettings.AllPrefs.DivineShield
                    && FeralKittySettings.AllPrefs.DivineShield == 2)
                {
                    return true;
                }
                if (FeralKittySettings.AllPrefs.DivineShield == 1)
                {
                    return true;
                }
                return false;
            }
        }
        public bool Dispersion
        {
            get
            {
                if (IsBoss
                    && Me.HealthPercent <= FeralKittySettings.AllPrefs.DivineShield
                    && FeralKittySettings.AllPrefs.Dispersion == 2)
                {
                    return true;
                }
                if (FeralKittySettings.AllPrefs.Dispersion == 1)
                {
                    return true;
                }
                return false;
            }
        }
        #endregion symbiosis

        #region UseSpells
        public bool UseSpells
        {
            get
            {
                if (Me.Mounted
                    || Me.IsGhost
                    || Me.IsDead)
                {
                    return false;
                }
                return true;
            }
        }
        #endregion UseSpells

        

        #region berserking
        public bool BerserKing
        {
            get
            {
                if (Me.Specialization == WoWSpec.DruidFeral)
                {
                    if (FeralKittySettings.AllPrefs.Berserking == 1
                        && !Me.HasAura("Bloodlust")
                        && !Me.HasAura("Time Warp")
                        && !Me.HasAura("Heroism")
                        && IsBoss)
                    {
                        return true;
                    }
                    if (FeralKittySettings.AllPrefs.Berserking == 2
                        && !Me.HasAura("Bloodlust")
                        && !Me.HasAura("Time Warp")
                        && !Me.HasAura("Heroism"))
                    {
                        return true;
                    }
                }
                if (Me.Specialization == WoWSpec.DruidGuardian)
                {
                    if (FeralKittySettings.AllPrefs.BerserkingBear == 1
                        && !Me.HasAura("Bloodlust")
                        && !Me.HasAura("Time Warp")
                        && !Me.HasAura("Heroism")
                        && IsBoss)
                    {
                        return true;
                    }
                    if (FeralKittySettings.AllPrefs.BerserkingBear == 2
                        && !Me.HasAura("Bloodlust")
                        && !Me.HasAura("Time Warp")
                        && !Me.HasAura("Heroism"))
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        #endregion Berserking

        #region CastBuff
        public void CastBuff(string spell, int kleurtje)
        {
            if (SpellManager.CanCast(spell))
            {
                SpellManager.Cast(spell, Me);
                LastSpell = spell;
                LogMsg(spell, kleurtje);
            }
        }
        #endregion CastBuff

        #region combopoints
        public int myComboPoints
        {
            get
            {
                int mePoints = 1;
                double delen = Me.CurrentTarget.MaxHealth / Me.MaxHealth;
                delen = Math.Round(delen, 0, MidpointRounding.ToEven);
                //LogMsg("delen is nu : " + delen, 8);
                if (IsBoss)
                {
                    mePoints = 5;
                }
                if (!IsBoss)
                {
                    if (delen == 1)
                    {
                        mePoints = 2;
                    }
                    if (delen == 2)
                    {
                        mePoints = 4;
                    }
                    if (delen > 2)
                    {
                        mePoints = 5;
                    }
                }
                return mePoints;
            }
        }
        #endregion combopoints

        #region glyphs
        public bool HaveGlyph(string glyph)
        {
            if (FeralKittySettings.AllPrefs.MajorGlyph1 == "Savagery")
            {
                return true;
            }
            if (FeralKittySettings.AllPrefs.MajorGlyph2 == "Savagery")
            {
                return true;
            }
            if (FeralKittySettings.AllPrefs.MajorGlyph3 == "Savagery")
            {
                return true;
            }
            return false;
        }
        #endregion glyphs

        #region logs
        public void LogMsg(string msg, int kleurtje)
        {
            LastSpell = msg;
            Color kleur = Colors.Yellow;
            switch (kleurtje)
            {
                case 0:
                    kleur = Colors.Orange;
                    break;
                case 1:
                    kleur = Colors.PaleGreen;
                    break;
                case 2:
                    kleur = Colors.BlanchedAlmond;
                    break;
                case 3:
                    kleur = Colors.Yellow;
                    break;
                case 4:
                    kleur = Colors.Red;
                    break;
                case 5:
                    kleur = Colors.Crimson;
                    break;
                case 6:
                    kleur = Colors.LightBlue;
                    break;
                case 7:
                    kleur = Colors.LightBlue;
                    break;
            }
            LastSpell = msg;
            Logging.Write(kleur, msg);
        }
        #endregion logs

        #region Kind of target
        public bool IsBoss
        {
            get
            {
                if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.WorldBoss)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.MaxHealth >= (65 * 1000000))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && target.IsBoss(Me.CurrentTarget))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.Specialization == WoWSpec.DruidFeral
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Elite
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * FeralKittySettings.AllPrefs.EliteHealth)
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.Specialization == WoWSpec.DruidFeral
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.RareElite
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * FeralKittySettings.AllPrefs.EliteHealth)
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.Specialization == WoWSpec.DruidFeral
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Rare
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * FeralKittySettings.AllPrefs.EliteHealth)
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.Specialization == WoWSpec.DruidGuardian
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Elite
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * FeralKittySettings.AllPrefs.EliteHealthBear)
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.Name.Contains("Training Dummy"))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.IsPlayer
                    && !Me.CurrentTarget.IsFriendly)
                {
                    return true;
                }
                return false;
            }
        }

        #endregion Kind of Target

        #region Movement
        public void MoveInRange(float dist)
        {
            if (Me.CurrentTarget != null)
            {
                float range = dist;
                while (Me.CurrentTarget != null
                    && StyxWoW.Me.Location.Distance(StyxWoW.Me.CurrentTarget.Location) > range)
                {
                    Navigator.MoveTo(StyxWoW.Me.CurrentTarget.Location);
                };
                Navigator.PlayerMover.MoveStop();
            }

        }
        #endregion Movement

        #region AddCounting
        private int addCount
        {
            get
            {
                if (gotTarget)
                {
                    int count = 0;
                    foreach (WoWUnit u in ObjectManager.GetObjectsOfType<WoWUnit>(true, true))
                    {
                        if (u.IsAlive
                            && u.CanSelect
                            && !u.IsPlayer
                            && u.Guid != Me.Guid
                            && !u.IsFriendly
                            && u.IsHostile
                            && u.Attackable
                            && !u.IsTotem
                            && !u.IsCritter
                            && !u.IsNonCombatPet
                            && !u.IsPet
                            && (u.Location.Distance(Me.CurrentTarget.Location) <= 8 || u.Location.Distance2D(Me.CurrentTarget.Location) <= 8))
                        {
                            count++;
                        }
                    }
                    return count;
                }
                return 0;
            }
        }
        #endregion AddCounting

        #region Trinkets
        public void UseTrinket1()
        {
            if (Me.Specialization == WoWSpec.DruidFeral)
            {
                if (Me.CurrentTarget != null)
                {
                    var firstTrinket = StyxWoW.Me.Inventory.Equipped.Trinket1;

                    if (FeralKittySettings.AllPrefs.Mtrinket1 != 0)
                    {
                        if (FeralKittySettings.AllPrefs.Mtrinket1 == 2
                            && IsBoss)
                        {

                            if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                            {
                                firstTrinket.Use();
                                LogMsg("Using 1st trinket", 2);
                            }
                        }
                        else if (FeralKittySettings.AllPrefs.Mtrinket1 == 1)
                        {
                            if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                            {
                                firstTrinket.Use();
                                LogMsg("Using 1st trinket", 2);
                            }
                        }
                    }
                }
            }
            if (Me.Specialization == WoWSpec.DruidGuardian)
            {
                if (Me.CurrentTarget != null)
                {
                    var firstTrinket = StyxWoW.Me.Inventory.Equipped.Trinket1;

                    if (FeralKittySettings.AllPrefs.Btrinket1Bear != 0)
                    {
                        if (FeralKittySettings.AllPrefs.Btrinket1Bear == 2
                            && IsBoss)
                        {

                            if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                            {
                                firstTrinket.Use();
                                LogMsg("Using 1st trinket", 2);
                            }
                        }
                        else if (FeralKittySettings.AllPrefs.Btrinket1Bear == 1)
                        {
                            if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                            {
                                firstTrinket.Use();
                                LogMsg("Using 1st trinket", 2);
                            }
                        }
                    }
                }
            }
        }
        void UseTrinket2()
        {
            if (Me.Specialization == WoWSpec.DruidFeral)
            {
                if (Me.CurrentTarget != null
                    && FeralKittySettings.AllPrefs.Mtrinket2 != 0)
                {
                    var secondTrinket = StyxWoW.Me.Inventory.Equipped.Trinket2;

                    if (FeralKittySettings.AllPrefs.Mtrinket2 == 2
                        && IsBoss)
                    {
                        if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                        {
                            secondTrinket.Use();
                            LogMsg("Using 2nd trinket", 2);
                        }
                    }
                    else if (FeralKittySettings.AllPrefs.Mtrinket2 == 1)
                    {
                        if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                        {
                            secondTrinket.Use();
                            LogMsg("Using 2nd trinket", 2);
                        }
                    }
                }
            }
            if (Me.Specialization == WoWSpec.DruidGuardian)
            {
                if (Me.CurrentTarget != null
                    && FeralKittySettings.AllPrefs.Btrinket2Bear != 0)
                {
                    var secondTrinket = StyxWoW.Me.Inventory.Equipped.Trinket2;

                    if (FeralKittySettings.AllPrefs.Btrinket2Bear == 2
                        && IsBoss)
                    {
                        if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                        {
                            secondTrinket.Use();
                            LogMsg("Using 2nd trinket", 2);
                        }
                    }
                    else if (FeralKittySettings.AllPrefs.Btrinket2Bear == 1)
                    {
                        if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                        {
                            secondTrinket.Use();
                            LogMsg("Using 2nd trinket", 2);
                        }
                    }
                }
            }
        }
        public void UseEngibelt()
        {
            if (Me.CurrentTarget != null
                && FeralKittySettings.AllPrefs.Mengibelt != 0)
            {
                var engiBelt = StyxWoW.Me.Inventory.Equipped.Waist;

                if (FeralKittySettings.AllPrefs.Mengibelt == 2
                    && IsBoss)
                {
                    if (engiBelt != null && CanUseEquippedItem(engiBelt))
                    {
                        engiBelt.Use();
                        LogMsg("Using Engineer Belt", 2);
                    }
                }
                else if (FeralKittySettings.AllPrefs.Mengibelt == 1)
                {
                    if (engiBelt != null && CanUseEquippedItem(engiBelt))
                    {
                        engiBelt.Use();
                        LogMsg("Using Engineer Belt", 2);
                    }
                }
            }
        }
        void UseEngiGloves()
        {
            if (Me.Specialization == WoWSpec.DruidFeral)
            {
                if (Me.CurrentTarget != null
                    && FeralKittySettings.AllPrefs.Mengigloves != 0)
                {
                    var engiGloves = StyxWoW.Me.Inventory.Equipped.Hands;

                    if (FeralKittySettings.AllPrefs.Mengigloves == 2
                        && IsBoss)
                    {
                        if (engiGloves != null && CanUseEquippedItem(engiGloves))
                        {
                            engiGloves.Use();
                            LogMsg("Using Engineer Gloves", 2);
                        }
                    }
                    else if (FeralKittySettings.AllPrefs.Mengigloves == 1)
                    {
                        if (engiGloves != null && CanUseEquippedItem(engiGloves))
                        {
                            engiGloves.Use();
                            LogMsg("Using Engineer Gloves", 2);
                        }
                    }
                }
            }
            if (Me.Specialization == WoWSpec.DruidGuardian)
            {
                if (Me.CurrentTarget != null
                    && FeralKittySettings.AllPrefs.BengiglovesBear != 0)
                {
                    var engiGloves = StyxWoW.Me.Inventory.Equipped.Hands;

                    if (FeralKittySettings.AllPrefs.BengiglovesBear == 2
                        && IsBoss)
                    {
                        if (engiGloves != null && CanUseEquippedItem(engiGloves))
                        {
                            engiGloves.Use();
                            LogMsg("Using Engineer Gloves", 2);
                        }
                    }
                    else if (FeralKittySettings.AllPrefs.BengiglovesBear == 1)
                    {
                        if (engiGloves != null && CanUseEquippedItem(engiGloves))
                        {
                            engiGloves.Use();
                            LogMsg("Using Engineer Gloves", 2);
                        }
                    }
                }
            }
        }
        private static bool CanUseEquippedItem(WoWItem item)
        {
            // Check for engineering tinkers!
            string itemSpell = Lua.GetReturnVal<string>("return GetItemSpell(" + item.Entry + ")", 0);
            if (string.IsNullOrEmpty(itemSpell))
                return false;


            return item.Usable && item.Cooldown <= 0;
        }
        #endregion Trinkets

        #region botbase
        public static string GetBotName()
        {
            BotBase bot = null;

            if (TreeRoot.Current != null)
            {
                if (!(TreeRoot.Current is NewMixedMode.MixedModeEx))
                    bot = TreeRoot.Current;
                else
                {
                    NewMixedMode.MixedModeEx mmb = (NewMixedMode.MixedModeEx)TreeRoot.Current;
                    if (mmb != null)
                    {
                        if (mmb.SecondaryBot != null && mmb.SecondaryBot.RequirementsMet)
                            return "Mixed:" + mmb.SecondaryBot.Name;
                        return mmb.PrimaryBot != null ? "Mixed:" + mmb.PrimaryBot.Name : "Mixed:[primary null]";
                    }
                }
            }

            return bot.Name;
        }

        public static bool usingBot(params string[] nameSubstrings)
        {
            string botName = GetBotName().ToUpper();
            return nameSubstrings.Any(s => botName.Contains(s.ToUpper()));
        }
        #endregion botbase

        #region abovetheground
        public static bool IsAboveTheGround(WoWUnit u)
        {
            float height = HeightOffTheGround(u);
            if (height > 3.5f)
            {
                return true;
            }

            return false;
        }

        public static float HeightOffTheGround(WoWUnit u)
        {
            var unitLoc = new WoWPoint(u.Location.X, u.Location.Y, u.Location.Z);
            var listMeshZ = Navigator.FindHeights(unitLoc.X, unitLoc.Y).Where(h => h <= unitLoc.Z);
            if (listMeshZ.Any())
            {
                return unitLoc.Z - listMeshZ.Max();
            }

            return float.MaxValue;
        }
        #endregion abovetheground

        #region get target
        public WoWUnit FindTarget()
        {
                WoWUnit newTarget = (from o in ObjectManager.ObjectList
                                     where o is WoWUnit
                                     let unit = o.ToUnit()
                                     where
                                         unit.Distance <= 8
                                         && !unit.IsFriendly
                                         && unit.CanSelect
                                         && !unit.IsCritter
                                         && !unit.IsPetBattleCritter
                                         && !unit.IsDead
                                         && !unit.IsPet
                                         && !Blacklist.Contains(unit.Guid, BlacklistFlags.All)
                                     orderby unit.Distance ascending
                                     select unit
                                     ).FirstOrDefault();
                return newTarget;
        } 
        Composite GetNewTarget()
        {
            return
                new Action(ret =>
                {
                    WoWUnit myTarget = FindTarget();
                    LogMsg("found new target " + myTarget.Name, 0);
                    myTarget.Target();
                });
        }
        #endregion get target

        #region pause
        public override void ShutDown()
        {
            Lua.Events.DetachEvent("MODIFIER_STATE_CHANGED", HandleModifierStateChanged);
        }

        private void HandleModifierStateChanged(object sender, LuaEventArgs args)
        {
            if (FeralKittySettings.AllPrefs.PauseKeys == FeralKittySettings.Keypress.None
                && FeralKittySettings.AllPrefs.BearFormKeys == FeralKittySettings.Keypress.None)
            {
                return;
            }

            if (Convert.ToInt32(args.Args[1]) == 1)
            {
                if (args.Args[0].ToString() == FeralKittySettings.AllPrefs.PauseKeys.ToString())
                {
                    Paused = !Paused;
                    if (Paused)
                    {
                        Logging.Write("FeralKitty PAUSED, press {0} in WOW to continue",
                                     FeralKittySettings.AllPrefs.PauseKeys.ToString());
                        if (FeralKittySettings.AllPrefs.PrintMsg)
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"FeralKitty PAUSED\", ChatTypeInfo[\"RAID_WARNING\"]);");
                    }
                    else
                    {
                        Logging.Write("FeralKitty Running....");
                        if (FeralKittySettings.AllPrefs.PrintMsg)
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"FeralKitty Resumed\", ChatTypeInfo[\"RAID_WARNING\"]);");
                    }
                }
                if (args.Args[0].ToString() == FeralKittySettings.AllPrefs.BearFormKeys.ToString())
                {
                    SwitchToBearForm = !SwitchToBearForm;

                    if (SwitchToBearForm)
                    {
                        Logging.Write("Switching to Bear Form, press {0} in WOW to switch back",
                                     FeralKittySettings.AllPrefs.BearFormKeys.ToString());
                        if (FeralKittySettings.AllPrefs.PrintMsg)
                        {
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"Switching to Bear Form, press " + FeralKittySettings.AllPrefs.BearFormKeys.ToString() + " again to switch back\", ChatTypeInfo[\"RAID_WARNING\"]);");
                        }
                    }
                    else
                    {
                        Logging.Write("Switching back to Cat Form ....");
                        if (FeralKittySettings.AllPrefs.PrintMsg)
                        {
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"Switching back to Cat Form\", ChatTypeInfo[\"RAID_WARNING\"]);");
                        }
                    }
                }
            }
        }
        #endregion pause

        #region UseForm
        public string UseForm
        {
            get
            {
                if (Me.Specialization == WoWSpec.DruidGuardian)
                {
                    return "Bear";
                }
                else if (SwitchToBearForm
                    && Me.Specialization == WoWSpec.DruidFeral)
                {
                    return "Bear";
                }
                else if (gotTarget
                    && buffExists(MightOfUrsoc, Me))
                {
                    return "Bear";
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.IsAlive
                    && FeralKittySettings.AllPrefs.ChooseForm == 1
                    && !SwitchToBearForm
                    && !Me.HasAura(MightOfUrsoc)
                    && Me.Specialization == WoWSpec.DruidFeral )
                {
                    return "Cat";
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.IsAlive
                    && FeralKittySettings.AllPrefs.ChooseForm == 2
                    && SpellManager.HasSpell("Bear Form")
                    && Me.Specialization == WoWSpec.DruidGuardian)
                {
                    return "Bear";
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.IsAlive
                    && !SwitchToBearForm
                    && FeralKittySettings.AllPrefs.ChooseForm == 0
                    && SpellManager.HasSpell("Bear Form")
                    && addCount >= FeralKittySettings.AllPrefs.UseBearForm
                    && (!Me.GroupInfo.IsInRaid
                    && !Me.IsInInstance)
                    && !Me.HasAura(MightOfUrsoc)
                    && Me.Specialization == WoWSpec.DruidFeral)
                {
                    return "Bear";
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.IsAlive
                    && !SwitchToBearForm
                    && FeralKittySettings.AllPrefs.ChooseForm == 0
                    && addCount < FeralKittySettings.AllPrefs.UseBearForm
                    && !Me.HasAura(MightOfUrsoc)
                    && Me.Specialization == WoWSpec.DruidFeral)
                {
                    return "Cat";
                }

                return "Cat";
            }
        }
        public Composite useCatForm()
        {
            return new Decorator(ret => UseForm == "Cat" && Me.Shapeshift != ShapeshiftForm.Cat && Me.Level >= 6,
            new Action(ret =>
            {
                SpellManager.Cast("Cat Form");
                LogMsg("Cat Form", 2);
            }));
        }
        public Composite useBearForm()
        {
            return new Decorator(ret => UseForm == "Bear" && Me.Shapeshift != ShapeshiftForm.Bear && Me.Level >= 8,
            new Action(ret =>
            {
                SpellManager.Cast("Bear Form");
                LogMsg("Bear Form", 2);
            }));
        }
        #endregion UseForm

        #region pulling
        public void CatPull()
        {
            if (Me.Shapeshift != ShapeshiftForm.Cat
                && SpellManager.HasSpell("Cat Form")
                && SpellManager.CanCast("Cat Form")
                && !Me.Mounted)
            {
                SpellManager.Cast("Cat Form");
                LogMsg("*** CatPull *** => Cat Form", 6);
            } 
            if (gotTarget
                && SpellManager.HasSpell(FF)
                && !FeralKittySettings.AllPrefs.useProwl
                && !spellOnCooldown(FF)
                && SpellManager.CanCast(FF))
            {
                MoveInRange(30f);
                Me.CurrentTarget.Face();
                SpellManager.Cast(FF);
                LogMsg("***CatPull *** => " + FF, 6);
            }
            if (gotTarget
                && FeralKittySettings.AllPrefs.useProwl
                && Me.HasAura("Prowl")
                && SpellManager.HasSpell("Pounce")
                && Me.EnergyPercent >= 50
                && SpellManager.CanCast("Pounce"))
            {
                MoveInRange(3.5f);
                Me.CurrentTarget.Face();
                SpellManager.Cast("Pounce");
                LogMsg("*** CatPull *** => Pounce", 6);
            }
            if (gotTarget
                && !Me.HasAura("Prowl")
                && SpellManager.CanCast("Mangle"))
            {
                MoveInRange(3.5f);
                Me.CurrentTarget.Face();
                SpellManager.Cast(Mangle);
                LogMsg("*** CatPull *** => Mangle", 6);
            }

        }
        public void BearPull()
        {
            if (Me.Shapeshift != ShapeshiftForm.Bear
                && SpellManager.HasSpell("Bear Form")
                && SpellManager.CanCast("Bear Form")
                && !Me.Mounted)
            {
                SpellManager.Cast("Bear Form");
                LogMsg("*** BearPull *** => Bear Form", 6);
            }
            if (gotTarget
                && SpellManager.HasSpell("Growl")
                && !spellOnCooldown(Growl)
                && SpellManager.CanCast("Growl"))
            {
                MoveInRange(30);
                Me.CurrentTarget.Face();
                SpellManager.Cast(Growl);
                LogMsg("*** BearPull *** => Growl", 6);
            }
            if (Me.CurrentTarget != null
                && SpellManager.HasSpell(FF)
                && !spellOnCooldown(FF)
                && SpellManager.CanCast(FF))
            {
                MoveInRange(30f);
                Me.CurrentTarget.Face();
                SpellManager.Cast(FF);
                LogMsg("*** BearPull *** => " + FF, 6);
            }
            if (gotTarget
                && SpellManager.HasSpell(LacerateBear)
                && SpellManager.CanCast(LacerateBear))
            {
                MoveInRange(5);
                Me.CurrentTarget.Face();
                SpellManager.Cast(LacerateBear);
                LogMsg("*** BearPull *** => Lacerate Bear", 6);
            }
        }
        #endregion pulling

        #region hasteauras
        public bool HaveHasteBuff
        {
            get
            {
                if(buffExists("Bloodlust", Me)
                    && buffExists("Time Warp", Me)
                    && buffExists("Heroism", Me)
                    && buffExists("Ancient Hysteria", Me))
                {
                    return true;
                }
                return false;
            }
        }
        #endregion hasteauras

        #region statsbuffs
        public bool HaveStatsBuff
        {
            get
            {
                if (buffExists("Mark of the Wild", Me)
                    || buffExists("Blessing of Kings", Me)
                    || buffExists("Legacy of the Emperor", Me))
                {
                    return true;
                }
                return false;
            }
        }
        #endregion statsbuff

        #region myFocus
        public Composite MyFocus()
        {
            return new Action(ret =>
            {
                Lua.DoString("Cast [@focus] Cyclone");
            });
        }
        #endregion myFocus
    }
}
